import { Injectable } from '@angular/core';

import { Observable, of } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';

import { environment } from '@env/environment';
import { HttpServer } from '@core/net/http-server';
import { UrlManager } from '@shared/url/url.manager';
import { Constant } from '@core/constant';
import { NavMenu } from '@core/config/nav.config';

const devMenu = [
  {
    name: 'demo',
    url: '/main/demo',
    icon: 'code'
  }
];

@Injectable()
export class SystemService {

  constructor(
    private http: HttpServer,
    private navMenu: NavMenu
  ) { }

  private _menus = [];

  get menus(): any[] {
    return environment.production ? this._menus : [ ...this._menus, ...devMenu];
  }

  menuLoading = false;

  addMenu(val: any): void {
    this._menus = val;
  }

  getMenus(): Observable<any[]> {
    this.menuLoading = true;
    if (localStorage.getItem(Constant.MENU_KEY)) {
      this.menuLoading = false;
      return of(JSON.parse(localStorage.getItem(Constant.MENU_KEY)));
    } else {
      return this.http.get<any[]>(UrlManager.menu.getMenuUrl, {})
        .pipe(
          catchError(err => {
            this.menuLoading = false;
            return err;
          }),
          tap(data => {
            localStorage.setItem(Constant.MENU_KEY, JSON.stringify(data));
            this.menuLoading = false;
          })
        );
    }
  }

  getMenuByPath(path: string): any[] {
    let item = null;
    this.visit((i, parent, depth) => {
      if (i[this.navMenu.path] === path) {
        item = i;
      }
    });
    const ret: any[] = [];
    if (!item) {
      return ret;
    }
    ret.splice(0, 0, item);
    return ret;
  }

  visit(callback: (item: any, parentMenu: any, depth?: number) => void): void {
    const inFn = (list: any[], parentMenu: any, depth: number) => {
      for (const item of list) {
        callback(item, parentMenu, depth);
        if (item[this.navMenu.children] && item[this.navMenu.children].length > 0) {
          inFn(item[this.navMenu.children], item, depth + 1);
        } else {
          item[this.navMenu.children] = [];
        }
      }
    };
    const menus = [
      {
        [this.navMenu.name]: '桌面',
        [this.navMenu.i18n]: 'dashboard',
        [this.navMenu.path]: '/main/dashboard'
      },
      ...this._menus
    ];
    inFn(menus, null, 0);
  }
}
